/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.csjung.games.gamenori.client.desktop;

import com.google.gwt.appengine.channel.client.Channel;
import com.google.gwt.appengine.channel.client.ChannelFactory;
import com.google.gwt.appengine.channel.client.ChannelFactory.ChannelCreatedCallback;
import com.google.gwt.appengine.channel.client.SocketError;
import com.google.gwt.appengine.channel.client.SocketListener;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;

import com.csjung.games.gamenori.client.event.OnMessageEvent;
import com.csjung.games.gamenori.client.event.UserListRefreshEvent;
import com.csjung.games.gamenori.shared.GamenoriRequestFactory;
import com.csjung.games.gamenori.shared.UserProxy;
import com.csjung.games.gamenori.shared.UserServiceRequest;

public class LoginWidget extends Composite {
  interface Binder extends UiBinder<Widget, LoginWidget> {
  }

  private static final Binder BINDER = GWT.create(Binder.class);
  
  private final GamenoriRequestFactory requestFactory;
  private final EventBus eventBus;
  
  private UserProxy userProxy;
  
  @UiField
  SpanElement name;
  @UiField
  Anchor logoutLink;

  public LoginWidget(GamenoriRequestFactory requestFactory, EventBus eventBus) {
    this.requestFactory = requestFactory;
    this.eventBus = eventBus;
    initWidget(BINDER.createAndBindUi(this));
  }

  @Override
  protected void onLoad() {

    UserServiceRequest request = requestFactory.userServiceRequest();
    String url = "http://" + Location.getHostName() + ":" + Location.getPort() + "/intro.jsp";
    request.createLogoutURL(url).to(new Receiver<String>() {
      @Override
      public void onSuccess(String response) {
        setLogoutUrl(response);
      }
    });
    
    request.getCurrentUser().to(new Receiver<UserProxy>() {
      @Override
      public void onSuccess(UserProxy response) {
        setUserProxy(response);
        setUserName(response.getNickname());
        System.out.println("LoginWidget-> createChannel:" + response.getChannelToken());
        ChannelFactory.createChannel(response.getChannelToken(), new ChannelCreatedCallback() {
          @Override
          public void onChannelCreated(Channel channel) {
            channel.open(new SocketListener() {
              @Override
              public void onOpen() {
                System.out.println("LoginWidget-> openChannel");
              }
              @Override
              public void onMessage(String message) {
                eventBus.fireEventFromSource(new OnMessageEvent(message), this);
              }
              @Override
              public void onError(SocketError error) {
                Window.alert("Error: " + error.getDescription());
              }
              @Override
              public void onClose() {
                Window.alert("Channel closed!");
              }
            });
          }
        });
        eventBus.fireEventFromSource(new UserListRefreshEvent(), this);
      }
    });
    request.fire();
  }

  public void setUserName(String userName) {
    name.setInnerText(userName);
  }

  public void setLogoutUrl(String url) {
    logoutLink.setHref(url);
  }

  /**
   * Squelch clicks of the logout link if no href has been set.
   */
  @UiHandler("logoutLink")
  void handleClick(ClickEvent e) {
    if ("".equals(logoutLink.getHref())) {
      e.stopPropagation();
    }
  }

  public UserProxy getUserProxy() {
    return userProxy;
  }

  public void setUserProxy(UserProxy userProxy) {
    this.userProxy = userProxy;
  }
}
